/*******************************************************************************
 * $Header$
 * $Revision$
 * $Date$
 *
 *==============================================================================
 *
 * Copyright (c) 2016-2020 
 * All rights reserved.
 * 
 * Created on 2017年1月12日
 *******************************************************************************/


package com.hualife.support.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.hualife.support.exception.BusinessException;



/**
 * TODO 此处填写 class 信息
 *
 * @author 孙小冬 (mailto:sunxiaodong001@hualife.cc)
 */
public class DateUtil {
	
	/**
	 * 获得当前的时间戳 格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getCurrentTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar c = Calendar.getInstance();
		Date date = c.getTime();
		return sdf.format(date);
	}
	/**
	 * @param pBirthday
	 *            yyyy-MM-dd
	 * @return
	 */
	public static int getAge(String pBirthday) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date birthDay;
		try {
			birthDay = sdf.parse(pBirthday);
			Calendar mBirthdayCalendar = Calendar.getInstance();
			mBirthdayCalendar.setTime(birthDay);
			Calendar mNowCalendar = Calendar.getInstance();
			int mAge = mNowCalendar.get(Calendar.YEAR)
					- mBirthdayCalendar.get(Calendar.YEAR);
			mBirthdayCalendar.add(Calendar.YEAR, mAge);
			if (mNowCalendar.before(mBirthdayCalendar)) {
				mAge--;
			}
			return mAge;
		} catch (ParseException e) {
			e.printStackTrace();
			throw new BusinessException("出生日期不合符yyyy-MM-dd格式");
		}
	}
	/**
	 * <b>根据时间戳获取其中的日期信息<b>
	 * 
	 * @param date
	 *            yyyy-MM-dd HH:mm:ss形式日期字符串
	 * @return yyyy-MM-dd
	 */
	public static String getDateByDateStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		String pattern = "yyyy-MM-dd";
		if (dateStr != null && dateStr.length() == pattern.length())
			sdf = new SimpleDateFormat(pattern);
		try {
			sdf.parse(dateStr);
			return dateStr.substring(0, 10).trim();
		} catch (ParseException e) {
			e.printStackTrace();
			throw new BusinessException("日期格式不合法");
		}
	}

	/**
	 * 根据起期和期间及其单位，获取止期
	 * 
	 * @param startTime
	 *            起期时间 yyyy-MM-dd HH:mm:ss
	 * @param interval
	 *            日期间隔
	 * @param intervalType
	 *            单位 D-日,M-月,Y-年,H-小时,m-分钟,s-秒
	 */
	public static String getTimeToAddDate(String startTime, int interval,
			String intervalType) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date date = sdf.parse(startTime);
			Calendar ca = Calendar.getInstance();
			ca.setTime(date);

			if ("D".equals(intervalType)) {
				ca.add(Calendar.DAY_OF_MONTH, interval);
			} else if ("M".equals(intervalType)) {
				ca.add(Calendar.MONTH, interval);
			} else if ("Y".equals(intervalType)) {
				ca.add(Calendar.YEAR, interval);
			} else if ("H".equals(intervalType)) {
				ca.add(Calendar.HOUR_OF_DAY, interval);
			} else if ("m".equals(intervalType)) {
				ca.add(Calendar.MINUTE, interval);
			} else if ("s".equals(intervalType)) {
				ca.add(Calendar.SECOND, interval);
			} else {
				throw new BusinessException("不支持的日期类型");
			}
			return sdf.format(ca.getTime());
		} catch (ParseException e) {
			throw new BusinessException("不支持的日期类型");
		}
	}
	
	/**
	 * <b>获取当前日期+时间<b> 类型：Date
	 * 
	 * @return 当前日期+时间
	 */
	public static Date getCurrentDateTime() {
		return new Date();
	}
	
	
	
	/**
	 * 获得当前日期的格式 yyyy-MM-dd
	 * 
	 * @返回 Date
	 */
	public static Date getCurrentDate_Date() {
		
		Date currentDate = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			currentDate = sdf.parse(getCurrentDate("yyyy-MM-dd"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return currentDate;
	}
	
	/**
	 * <b>获得当前日期</b>
	 * 
	 * @return 日期格式为:yyyy-MM-dd
	 */
	public static String getCurrentDate() {
		return getCurrentDate("yyyy-MM-dd");
	}
	
	/**
	 * <b>获得当前日期</b>
	 * 
	 * @param pattern
	 *            日期格式
	 * @return
	 */
	public static String getCurrentDate(String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Calendar c = Calendar.getInstance();
		Date date = c.getTime();
		return sdf.format(date);
	}
	
	/**
	 * 获得当前时间格式的字符串(24小时制 HH:mm:ss)
	 */
	public static String get_HHmmss_time() {
		String dt = "";
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
			Calendar cal = Calendar.getInstance();
			dt = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dt;
	}
	
	/**
	 * 计算两日期之间的天数
	 * 
	 * @param: start 开始日期
	 * @param: end 截止日期
	 * @return: int
	 * @createDate: 2013-4-24
	 */
	public static int getDaysBetween(Date start, Date end) {
		if (start == null || end == null) {
			return 0;
		}

		boolean negative = false;
		if (end.before(start)) {
			negative = true;
			Date temp = start;
			start = end;
			end = temp;
		}
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(start);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		GregorianCalendar calEnd = new GregorianCalendar();
		calEnd.setTime(end);
		calEnd.set(Calendar.HOUR_OF_DAY, 0);
		calEnd.set(Calendar.MINUTE, 0);
		calEnd.set(Calendar.SECOND, 0);
		calEnd.set(Calendar.MILLISECOND, 0);

		if (cal.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR)) {
			if (negative) {
				return (calEnd.get(Calendar.DAY_OF_YEAR) - cal
						.get(Calendar.DAY_OF_YEAR)) * -1;
			} else {
				return calEnd.get(Calendar.DAY_OF_YEAR)
						- cal.get(Calendar.DAY_OF_YEAR);
			}
		}
		int counter = 0;
		while (calEnd.after(cal)) {
			cal.add(Calendar.DAY_OF_YEAR, 1);
			counter++;
		}
		if (negative) {
			return counter * -1;
		} else {
			return counter;
		}
	}

	/**
	 * 计算某日期之后N(天，月，年)的日期
	 * 
	 * @param startDate
	 *            起期时间 yyyy-MM-dd
	 * @param interval
	 *            日期间隔
	 * @param intervalType
	 *            单位 D-日,M-月,Y-年
	 */
	public static String getDateToAddDate(String startDate, int interval,
			String intervalType) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = sdf.parse(startDate);
			Calendar ca = Calendar.getInstance();
			ca.setTime(date);

			if ("D".equals(intervalType)) {
				ca.add(Calendar.DAY_OF_MONTH, interval);
			} else if ("M".equals(intervalType)) {
				ca.add(Calendar.MONTH, interval);
			} else if ("Y".equals(intervalType)) {
				ca.add(Calendar.YEAR, interval);
			} else {
				throw new BusinessException("不支持的日期类型");
			}
			return sdf.format(ca.getTime());
		} catch (ParseException e) {
			throw new BusinessException("不支持的日期类型");
		}
	}

	/**
	 * <b>日期字转化为符串Date<b>
	 * 
	 * @param 日期
	 *            Date
	 * @return date 字符串 格式：yyyy-MM-dd HH:mm:ss
	 */
	public static String getStrFromDate(Date date) {
		String dateStr = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			dateStr = sdf.format(date);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BusinessException("日期类型转化错误");
		}
		return dateStr;
	}
	public static boolean validateDate24Time(String time) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		try {
			sdf.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
		if (!(validateDate(time.substring(0, 10)))) {
			return false;
		}

		return (validate24Time(time.substring(11)));
	}
	public static boolean validateDate(String date) {
		boolean validateFlag = false;
		// 正则表达式校验
		if (date != null && date.trim().length() == 10) {
			Pattern pattern = Pattern
					.compile("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)");
			Matcher matcher = pattern.matcher(date);
			validateFlag = matcher.matches();
		}
		return validateFlag;
	}
	public static boolean validate24Time(String time) {
		boolean validateFlag = false;
		// 正则表达式校验
		if (time != null && time.trim().length() == 8) {
			Pattern pattern = Pattern
					.compile("^((1|0?)[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])");
			Matcher matcher = pattern.matcher(time);
			validateFlag = matcher.matches();
		}
		return validateFlag;
	}
	/**
	 * <b>根据时间戳获取其中的时间信息<b>
	 * 
	 * @param date
	 *            yyyy-MM-dd HH:mm:ss形式日期字符串
	 * @return HH:mm:ss
	 */
	public static String getTimeByDateStr(String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String pattern = "HH:mm:ss";
		try {
			sdf.parse(dateStr);
			return dateStr.substring(dateStr.length() - pattern.length(),
					dateStr.length()).trim();
		} catch (ParseException e) {
			e.printStackTrace();
			throw new BusinessException("日期格式不合法");
		}
	}
	
	/**
	 * <b>判断字符串是否为日期格式 yyyy-MM-dd HH:mm:ss
	 * 
	 * @return boolean
	 * 	 */
	public static boolean isValidDate(String str) {
		boolean convertSuccess = true;
		// 指定日期格式为四位年-两位月份-两位日期 ，注意yyyy-MM-dd HH:mi:ss区分大小写；
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			// 设置lenient为false.
			// 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(str);
		} catch (ParseException e) {
			// e.printStackTrace();
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess = false;
		}
		return convertSuccess;

	}
 
	
	/*
	 * 获得当前日期的格式 yyyy-MM-dd
	 * 
	 * @返回 String
	 */
	public static String get_YYYY_MM_DD_Date() {
		String dt = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar cal = Calendar.getInstance();
			dt = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dt;
	}
	/*
	 * 获取yyyy-MM-dd的日期
	 */
	public static String getYYYY_MM_DD_Date(String dateStr) {
		String dt = "";
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			dt = sdf.format(parse(dateStr));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dt;
	}
	public static Date parse(String s) throws java.text.ParseException {
		if (s == null || "".equals(s.trim())) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.parse(s);
	}
	
	/**
	 * <b>将Date转化为标准字符串</b>
	 * 
	 * @param date
	 * @return yyyy年MM月dd日 HH时mm分ss秒
	 */
	public static String formatDate2Cn(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
		String dateString = sdf.format(date);
		return dateString;
	}
	
	public static String getDateChn(String date){
		try {
			return DateUtil.formatDate2Cn(new SimpleDateFormat("yyyy-MM-dd").parse(date)).substring(0,11);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	
	// 将时间转换为到分
	public static String getDateChnToMinute(String date) {
		try {
			return DateUtil.formatDate2Cn(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date)).substring(0, 18);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return "";
	}
	/**
	 * <b>日期字转化为符串Date<b>
	 * 
	 * @param 日期
	 *            Date
	 * @return date 字符串 格式：yyyy-MM-dd 
	 */
	public static String getYYYYMMDDStrFromDate(Date date) {
		String dateStr = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			dateStr = sdf.format(date);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BusinessException("日期类型转化错误");
		}
		return dateStr;
	}
	
	/**
	 * <b>字符串转化为日期Date,若传入null或者空串，直接返回null<b>
	 * 
	 * @param 字符串
	 *            格式 yyyy-MM-dd HH:mm:ss
	 * @return 日期Date 格式：yyyy-MM-dd HH:mm:ss
	 */
	public static Date getDateFromStr(String dateStr) {
		Date date = null;
		if (dateStr == null || "".equals(dateStr))
			return date;
		try {
			date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BusinessException("日期类型转化错误");
		}
		return date;
	}
	/**
	 * <p>
	 * 获取当前的格林威治时间
	 * </p>
	 * 
	 * @param timeString
	 *            日期格式:yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static long getGreenwich() {
		Calendar c = Calendar.getInstance();
		Date date = c.getTime();
		return date.getTime();
	}
	public static String date8to10(String date) throws ParseException {
		SimpleDateFormat sf1 = new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat sf2 = new SimpleDateFormat("yyyy-MM-dd");
		return sf2.format(sf1.parse(date));
	}

	public static String time6to8(String time) throws ParseException {
		SimpleDateFormat sf1 = new SimpleDateFormat("HHmmss");
		SimpleDateFormat sf2 = new SimpleDateFormat("HH:mm:ss");
		return sf2.format(sf1.parse(time));
	}

	public static String date10to8(String date) throws ParseException {
		SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sf2 = new SimpleDateFormat("yyyyMMdd");
		return sf2.format(sf1.parse(date));
	}

	public static String time8to6(String time) throws ParseException {
		SimpleDateFormat sf1 = new SimpleDateFormat("HH:mm:ss");
		SimpleDateFormat sf2 = new SimpleDateFormat("HHmmss");
		return sf2.format(sf1.parse(time));
	}
	/**
	 * 根据起期和期间及其单位，获取止期
	 * 
	 * @param startTime
	 *            起期时间 yyyy-MM-dd HH:mm:ss
	 * @param interval
	 *            日期间隔
	 * @param intervalType
	 *            单位 D-日,M-月,Y-年,H-小时,m-分钟,s-秒
	 * @return Date 日期格式的计算结果
	 */
	public static Date getTimeToAddDate(Date startTime, int interval,
			String intervalType) {
		Calendar ca = Calendar.getInstance();
		ca.setTime(startTime);

		if ("D".equals(intervalType)) {
			ca.add(Calendar.DAY_OF_MONTH, interval);
		} else if ("M".equals(intervalType)) {
			ca.add(Calendar.MONTH, interval);
		} else if ("Y".equals(intervalType)) {
			ca.add(Calendar.YEAR, interval);
		} else if ("H".equals(intervalType)) {
			ca.add(Calendar.HOUR_OF_DAY, interval);
		} else if ("m".equals(intervalType)) {
			ca.add(Calendar.MINUTE, interval);
		} else if ("s".equals(intervalType)) {
			ca.add(Calendar.SECOND, interval);
		} else {
			throw new BusinessException("不支持的日期类型");
		}
		return ca.getTime();
	}
	/**
	 * <b>获得当前的时间,时分秒</b>
	 * 
	 * @param pattern
	 *            日期格式
	 * @return
	 */
	public static String getCurrentTime(String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Calendar c = Calendar.getInstance();
		Date now = c.getTime();
		return sdf.format(now);
	}


   /**
	 * <b>将Date转化为标准字符串</b>
	 * 
	 * @param date
	 * @return yyyy-MM-dd
	 */
	public static String formatDate2yMd(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = sdf.format(date);
		return dateString;
	}
	/**
	 * <p>获得指定日志的格林威治时间戳</p>
	 * @param timeString	日期格式:yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static long getGreenwich(String timeString) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date;
		try {
			date = sdf.parse(timeString);
			return date.getTime();
		} catch (ParseException e) {
			throw new BusinessException("日期不符合[yyyy-MM-dd HH:mm:ss]格式");
		}
	}

	 /**
     * 判断2个时间相差多少天、多少小时、多少分<br>
     * <br>
     * @param pBeginTime 请假开始时间<br>
     * @param pEndTime 请假结束时间<br>
     * @return String 计算结果<br>
     * @Exception 发生异常<br>
     */
 public static Long TimeDiff(String pBeginTime, String pEndTime) throws Exception {
	  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	  Long beginL = format.parse(pBeginTime).getTime();
	  Long endL = format.parse(pEndTime).getTime();
//	  Long day = (endL - beginL)/86400000;
//	  Long hour = ((endL - beginL)%86400000)/3600000;
	  Long min = ((endL - beginL))/60000;
//	  Long min = ((endL - beginL)%86400000%3600000)/60000;
//	  return ("实际请假" + day + "天" + hour + "小时" + min+"分钟");
	  return min;
 }
 
 /*
	 * 获得当前时间格式的字符串(24小时制)
	 */
	public static String get_HHmmssms() {
		String dt = "";
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("HHmmssms");
			Calendar cal = Calendar.getInstance();
			dt = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dt;
	}
	/**
	 * 得到两个日期之间的天数
	 * 格式yyyy-MM-dd HH:mm:ss
	 */
 public static String getEndDaySubStarDay(String startTime,String endTime){
	 SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			long start = format.parse(startTime).getTime();
			long end = format.parse(endTime).getTime();
			return (end-start)/60/60/24/1000+"";
		} catch (ParseException e) {
			throw new BusinessException("日期不符合[yyyy-MM-dd HH:mm:ss]格式");
		}
 }
 
	/**
	 * 根据指定日期计算相差一定天数的日期
	 * @param referDate 参照日期
	 * @param diff 正值为参照日期之后的某一天，负值为参照日期之前的某一天
	 * @return
	 */
	public static Date getDayByDiff(Date referDate, int diff) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Calendar date = Calendar.getInstance();
			date.setTime(referDate);
			date.set(Calendar.DATE, date.get(Calendar.DATE) + diff);
			Date endDate = sdf.parse(sdf.format(date.getTime()));
			return endDate;
		} catch (ParseException e) {
			throw new BusinessException("日期不符合[yyyy-MM-dd]格式");
		}
	}
	
	/**
	 * 根据当前日期计算相差一定天数的日期
	 * @param diff 正值为当前日期之后的某一天，负值为当前日期之前的某一天
	 * @return
	 */
	public static Date getDayByDiff(int diff) {
		return getDayByDiff(new Date(), diff);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("getGreenwich():"+getGreenwich());
		System.out.println("get_HHmmss_time():"+get_HHmmss_time());
		System.out.println("getCurrentDate():"+getCurrentDate());
		System.out.println("getCurrentDateTime():"+getCurrentDateTime());
		System.out.println("getCurrentDate_Date():"+getCurrentDate_Date());

		System.out.println("get_HHmmssms():"+get_HHmmssms());
		
	}


}

/**
 * 修改历史
 * $Log$ 
 */